package com.hghivln.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hghivln.constants.Constants;
import com.hghivln.mapper.InventoryLogMapper;
import com.hghivln.mapper.MedicinesMapper;
import com.hghivln.mapper.PurchaseItemMapper;
import com.hghivln.mapper.PurchaseMapper;
import com.hghivln.pojo.domain.*;
import com.hghivln.pojo.dto.PurchaseDto;
import com.hghivln.pojo.dto.PurchaseFormDto;
import com.hghivln.pojo.dto.PurchaseItemDto;
import com.hghivln.pojo.vo.AjaxResult;
import com.hghivln.service.PurchaseService;
import com.hghivln.utils.IdGeneratorSnowflake;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;


@Service
public class PurchaseServiceImpl implements PurchaseService {

    @Autowired
    private PurchaseMapper purchaseMapper;

    @Autowired
    private PurchaseItemMapper purchaseItemMapper;

    @Autowired
    private InventoryLogMapper inventoryLogMapper;

    @Autowired
    private MedicinesMapper medicinesMapper;


    @Override
    public AjaxResult listPurchaseForPage(PurchaseDto purchaseDto) {
        Page<Purchase> page = new Page<>(purchaseDto.getPageNum(), purchaseDto.getPageSize());
        QueryWrapper<Purchase> qw = new QueryWrapper<>();
        qw.eq(StringUtils.isNotBlank(purchaseDto.getProviderId()), Purchase.COL_PROVIDER_ID, purchaseDto.getProviderId());
        qw.like(StringUtils.isNotBlank(purchaseDto.getApplyUserName()), Purchase.COL_APPLY_USER_NAME, purchaseDto.getApplyUserName());
        qw.eq(StringUtils.isNotBlank(purchaseDto.getStatus()), Purchase.COL_STATUS, purchaseDto.getStatus());
        qw.orderByDesc(Purchase.COL_CREATE_TIME);
        purchaseMapper.selectPage(page, qw);
        return AjaxResult.success("查询成功", page.getRecords(), page.getTotal());
    }

    @Override
    public List<PurchaseItem> getPurchaseItemById(String purchaseId) {
        QueryWrapper<PurchaseItem> qw = new QueryWrapper<>();
        qw.eq(Purchase.COL_PURCHASE_ID, purchaseId);
        return purchaseItemMapper.selectList(qw);
    }

    /**
     * 入库单状态 1未提交 2待审核 3审核通过 4审核失败 5作废 6入库成功
     */
    @Override
    public AjaxResult doAudit(String purchaseId, SimpleUser simpleUser) {
        Purchase purchase = purchaseMapper.selectById(purchaseId);
        // 入库状态为 未提交 或 审核失败才能 提交审核
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1) || purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4)) {
            purchase.setStatus(Constants.STOCK_PURCHASE_STATUS_2);
            purchase.setApplyUserName(simpleUser.getUserName());
            purchase.setApplyUserId(Long.valueOf(simpleUser.getUserId().toString()));
            return AjaxResult.success(purchaseMapper.updateById(purchase));
        } else {
            return AjaxResult.fail("当前单据状态不是【未提交】或【审核失败】状态，不能提交审核");
        }
    }

    @Override
    public AjaxResult doInvalid(String purchaseId) {
        Purchase purchase = purchaseMapper.selectById(purchaseId);
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1) || purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4)) {
            purchase.setStatus(Constants.STOCK_PURCHASE_STATUS_5);
            return AjaxResult.success(purchaseMapper.updateById(purchase));
        } else if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_5)) {
            return AjaxResult.success("当前单据已【作废】，不可重复");
        }
        else {
            return AjaxResult.fail("当前单据状态不是【未提交】或【审核失败】状态，不能作废");
        }
    }

    @Override
    public AjaxResult auditPass(String purchaseId) {
        Purchase purchase = purchaseMapper.selectById(purchaseId);
        // 未入库状态
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_2)) {
            purchase.setStatus(Constants.STOCK_PURCHASE_STATUS_3);
            return AjaxResult.success(purchaseMapper.updateById(purchase));
        } else {
            return AjaxResult.fail("错误，当前单据状态不是【未审核】状态");
        }
    }

    @Override
    public AjaxResult auditNoPass(String purchaseId, String auditMsg) {
        Purchase purchase = purchaseMapper.selectById(purchaseId);
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_2)) {
            purchase.setStatus(Constants.STOCK_PURCHASE_STATUS_4);
            purchase.setExamine(auditMsg);
            return AjaxResult.success(purchaseMapper.updateById(purchase));
        } else {
            return AjaxResult.fail("错误，当前单据状态不是【未审核】状态");
        }
    }

    /**
     * 判断采购单ID在数据库里面是否存在，存在，并且状态是未审核或审核失败 可以暂存
     * 如果采购单号存在，则删除之前的采购单主表数据和采购单详情数据
     * 如果采购单号不存在，直接保存采购单主表数据和采购单详情数据
     */
    @Override
    public AjaxResult addPurchase(PurchaseFormDto purchaseFormDto) {
        Purchase purchase = purchaseMapper.selectById(purchaseFormDto.getPurchaseDto().getPurchaseId());
        // 判断ID在数据库里面是否存在，存在，并且状态是未审核或审核失败 可以暂存
        if (purchase != null && (purchaseFormDto.getPurchaseDto().getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1) || purchaseFormDto.getPurchaseDto().getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4))) {
            // 删除之前的采购单主表数据和采购单详情数据
            //purchaseMapper.deleteById(purchase.getPurchaseId());
            QueryWrapper<PurchaseItem> qw = new QueryWrapper<>();
            qw.eq(PurchaseItem.COL_PURCHASE_ID, purchase.getPurchaseId());
            purchaseItemMapper.delete(qw);

            // 保存采购单主表数据和采购单详情数据
            Purchase newPurchase = new Purchase();
            BeanUtils.copyProperties(purchaseFormDto.getPurchaseDto(), newPurchase);
            newPurchase.setStatus(Constants.STOCK_PURCHASE_STATUS_1);
            newPurchase.setUpdateBy(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            int a = purchaseMapper.updateById(newPurchase);
            return getAjaxResult(purchaseFormDto, newPurchase,a);
        } else if (purchase == null) { // ID在数据库中不存在，可以暂存
            // 保存采购单主表数据和采购单详情数据
            Purchase newPurchase = new Purchase();
            BeanUtils.copyProperties(purchaseFormDto.getPurchaseDto(), newPurchase);
            newPurchase.setStatus(Constants.STOCK_PURCHASE_STATUS_1); // 状态改为 未提交
            newPurchase.setCreateBy(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            newPurchase.setCreateTime(DateUtil.date());
            int a = purchaseMapper.insert(newPurchase);
            return getAjaxResult(purchaseFormDto, newPurchase,a);
        } else {
            return AjaxResult.fail("当前单据状态不是【未提交】或【审核失败】状态，不能进行修改");
        }
    }

    private AjaxResult getAjaxResult(PurchaseFormDto purchaseFormDto, Purchase newPurchase,int a) {

        for (PurchaseItemDto purchaseItemDto : purchaseFormDto.getPurchaseItemDtos()) {
            PurchaseItem purchaseItem = new PurchaseItem();
            BeanUtils.copyProperties(purchaseItemDto, purchaseItem);
            purchaseItem.setPurchaseId(newPurchase.getPurchaseId());
            purchaseItem.setItemId(IdGeneratorSnowflake.snowflakeId().toString());
            purchaseItemMapper.insert(purchaseItem);
        }
        return AjaxResult.success(a);
    }

    /**
     * 判断采购单ID在数据库里面是否存在，存在，并且状态是未审核或审核失败 可以 直接添加暂存并提交审核
     * 如果采购单号存在，则更新之前的采购单主表数据和删除采购单详情数据
     * 如果采购单号不存在，直接保存采购单主表数据和采购单详情数据
     */
    @Override
    public AjaxResult addPurchaseToAudit(PurchaseFormDto purchaseFormDto) {
        Purchase purchase = purchaseMapper.selectById(purchaseFormDto.getPurchaseDto().getPurchaseId());
        // 判断ID在数据库里面是否存在，存在，并且状态是未审核或审核失败 可以暂存
        if (purchase != null && (purchaseFormDto.getPurchaseDto().getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1) || purchaseFormDto.getPurchaseDto().getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4))) {
            // 删除之前的采购单主表数据和采购单详情数据
            //purchaseMapper.deleteById(purchase.getPurchaseId());
            QueryWrapper<PurchaseItem> qw = new QueryWrapper<>();
            qw.eq(PurchaseItem.COL_PURCHASE_ID, purchase.getPurchaseId());
            purchaseItemMapper.delete(qw);
            // 保存采购单主表数据和采购单详情数据
            Purchase newPurchase = new Purchase();
            BeanUtils.copyProperties(purchaseFormDto.getPurchaseDto(), newPurchase);
            newPurchase.setStatus(Constants.STOCK_PURCHASE_STATUS_2); // 状态改为 未审核
            newPurchase.setUpdateBy(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            newPurchase.setApplyUserId(Long.valueOf(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserId().toString()));
            newPurchase.setApplyUserName(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            int a = purchaseMapper.updateById(newPurchase);
            return getAjaxResult(purchaseFormDto, newPurchase,a);

        } else if (purchase == null){
            // 保存采购单主表数据和采购单详情数据
            Purchase newPurchase = new Purchase();
            BeanUtils.copyProperties(purchaseFormDto.getPurchaseDto(), newPurchase);
            newPurchase.setStatus(Constants.STOCK_PURCHASE_STATUS_2);
            newPurchase.setCreateBy(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            newPurchase.setCreateTime(DateUtil.date());
            newPurchase.setApplyUserId(Long.valueOf(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserId().toString()));
            newPurchase.setApplyUserName(purchaseFormDto.getPurchaseDto().getSimpleUser().getUserName());
            int a = purchaseMapper.insert(newPurchase);
            return getAjaxResult(purchaseFormDto, newPurchase,a);

        } else {
            return AjaxResult.fail("当前单据状态不是【未提交】或【审核失败】状态，不能进行修改");
        }
    }


    /**
     * 1、只有在审核通过的条件下才能入库
     * 更新入库详情（inventory_log表） 和 药品库存量（药品信息表） 和 修改单据的状态为入库成功（purchase表）
     * 2、已入库的不能重复入库
     */
    @Override
    public AjaxResult doInventory(String purchaseId, SimpleUser simpleUser) {
        Purchase purchase = purchaseMapper.selectById(purchaseId);
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_3)) {
            // 入库
            QueryWrapper<PurchaseItem> qw = new QueryWrapper<>();
            qw.eq(PurchaseItem.COL_PURCHASE_ID, purchase.getPurchaseId());
            List<PurchaseItem> purchaseItemList = purchaseItemMapper.selectList(qw);
            for (PurchaseItem purchaseItem : purchaseItemList) {

                Medicines medicines = medicinesMapper.selectById(purchaseItem.getMedicinesId());
                if (medicines.getDelFlag().equals(Constants.DEL_TRUE)) {
                    return AjaxResult.fail("错误，没有该药品");
                }

                InventoryLog inventoryLog = new InventoryLog();
                inventoryLog.setCreateBy(simpleUser.getUserName());
                inventoryLog.setCreateTime(new Date());
                inventoryLog.setUnit(purchaseItem.getUnit());
                inventoryLog.setConversion(purchaseItem.getConversion()); // 换算量
                inventoryLog.setProducterId(purchaseItem.getProducterId()); // 生产厂家ID
                inventoryLog.setPrescriptionType(purchaseItem.getPrescriptionType()); // 处方类型
                inventoryLog.setMedicinesType(purchaseItem.getMedicinesType()); // 药品类型
                inventoryLog.setMedicinesName(purchaseItem.getMedicinesName()); // 药品名称
                inventoryLog.setBatchNumber(purchaseItem.getBatchNumber()); // 处方总额
                inventoryLog.setTradePrice(purchaseItem.getTradePrice()); // 批发价
                inventoryLog.setTradeTotalAmount(purchaseItem.getTradeTotalAmount()); // 批发额
                inventoryLog.setMedicinesId(purchaseItem.getMedicinesId()); // 药品id
                inventoryLog.setPurchaseId(purchaseItem.getPurchaseId()); // 采购单据id
                inventoryLog.setInventoryLogNum(purchaseItem.getPurchaseNumber()); // 入库数量
                inventoryLog.setBatchNumber(purchaseItem.getBatchNumber()); // 药品生产批次号
                inventoryLog.setInventoryLogId(purchaseItem.getItemId()); // 详情id
                inventoryLog.setProviderId(purchase.getProviderId()); // 供应商ID
                inventoryLog.setPrescriptionPrice(medicines.getPrescriptionPrice());  // 处方价
                inventoryLog.setPrescriptionTotalAmount(medicines.getPrescriptionPrice().multiply(BigDecimal.valueOf(inventoryLog.getInventoryLogNum()))); // 处方总额
                inventoryLogMapper.insert(inventoryLog);

                // 更新药品库存量
                medicines.setMedicinesStockNum(medicines.getMedicinesStockNum() + purchaseItem.getPurchaseNumber());
                medicines.setUpdateBy(simpleUser.getUserName());
                medicinesMapper.updateById(medicines);

                // 修改单据的状态为入库成功
                purchase.setStatus(Constants.STOCK_PURCHASE_STATUS_6);
                purchase.setStorageOptTime(DateUtil.date());
                purchase.setStorageOptUser(simpleUser.getUserName());
                return AjaxResult.success(purchaseMapper.updateById(purchase));
            }
        } else if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_6)) {
            return AjaxResult.fail("采购单【" + purchaseId + "】已入库，不能重复入库");
        }
        return AjaxResult.fail("采购单【" + purchaseId + "】没有审核通过，不能入库");
    }

    @Override
    public AjaxResult selectPurchaseAndItemByPurchaseId(String purchaseId) {
        Purchase purchase = purchaseMapper.selectByPurchaseId(purchaseId);
        if (purchase == null) {
            return AjaxResult.fail("单据号【" + purchaseId + "】不存在");
        } else {
            List<PurchaseItem> purchaseItemList = getPurchaseItemById(purchaseId);
            HashMap<String, Object> map = new HashMap<>();
            map.put("purchase", purchase);
            map.put("items", purchaseItemList);
            return AjaxResult.success(map);
        }
    }
}
